package mint.mvc.core;

import java.io.IOException;
import java.util.logging.Logger;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 
 * DispatcherServlet must be mapped to root URL "/". It handles ALL requests 
 * from clients, and dispatches to appropriate handler to handle each request.
 * 
 * @author Michael Liao (askxuefeng@gmail.com)
 * @author LiangWei(895925636@qq.com)
 * @date 2015年3月13日 下午9:10:43 
 *
 */
@WebServlet(asyncSupported = true) 
public class ServiceServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	private Logger log = Logger.getLogger(this.getClass().getName());

	private Dispatcher dispatcher;
	private StaticFileHandler staticFileHandler;
	private ActionExecutor actionExecutor;
	
	private boolean handleStatic = false;
	
	@Override
	public void init(final ServletConfig servletConfig) throws ServletException {
		super.init(servletConfig);
		log.info("Init ServiceServlet...");
		this.dispatcher = new Dispatcher();
		this.actionExecutor = new ActionExecutor();
		
		Config config = new Config() {
			public String getInitParameter(String name) {
				return servletConfig.getInitParameter(name);
			}

			public ServletContext getServletContext() {
				return servletConfig.getServletContext();
			}
		};
		
		this.handleStatic = Boolean.valueOf(servletConfig.getInitParameter("handleStatic"));
		this.dispatcher.init(config);
		this.actionExecutor.init(config);
		
		if(handleStatic){
			this.staticFileHandler = new StaticFileHandler(servletConfig);
		}
		ActionContext.setWebRoot(servletConfig.getServletContext().getContextPath());
	}

	@Override
	public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException {
		HttpServletRequest 	httpReq 	= (HttpServletRequest) req;
		HttpServletResponse httpResp 	= (HttpServletResponse) resp;
		String 				method 		= httpReq.getMethod();
		
		if ("GET".equals(method) || "POST".equals(method) || "PUT".equals(method) || "DELETE".equals(method)) {
			/*进入处理请求*/
			Action action = dispatcher.dispatch(httpReq);
			if (action != null) {
				actionExecutor.executeAction(httpReq, httpResp, action);
			} else if(handleStatic && "GET".equals(method)){
				staticFileHandler.handle(httpReq, httpResp);
			} else {
				httpResp.sendError(HttpServletResponse.SC_NOT_FOUND);
			}
			return;
		}
		
		httpResp.sendError(HttpServletResponse.SC_NOT_ACCEPTABLE);
	}

	@Override
	public void destroy() {
		log.info("Destroy DispatcherServlet...");
		this.dispatcher.destroy();
	}
}